package edu.zcmu.seckill.service.impl;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import edu.zcmu.seckill.entity.Policy;
import edu.zcmu.seckill.entity.SeckillOrder;
import edu.zcmu.seckill.entity.User;
import edu.zcmu.seckill.exception.MyException;
import edu.zcmu.seckill.mapper.UserMapper;
import edu.zcmu.seckill.response.R;
import edu.zcmu.seckill.response.ResultCode;
import edu.zcmu.seckill.service.PolicyService;
import edu.zcmu.seckill.service.SeckillOrderService;
import edu.zcmu.seckill.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.zcmu.seckill.utils.GetAgeUtil;
import edu.zcmu.seckill.utils.JwtUtil;
import edu.zcmu.seckill.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author 唐诗
 * @since 2022-02-17
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    SeckillOrderService seckillOrderService;

    @Autowired
    PolicyService policyService;

    @Autowired
    RedisTemplate redisTemplate;
    @Override
    public R login(LoginVo loginVo) {
        String idcard = loginVo.getIdcard();
        String password = loginVo.getPassword();
        if (StringUtils.isEmpty(idcard)||StringUtils.isEmpty(password)){
            throw new MyException(ResultCode.ERROR,"填写项不允许为空");
        }
        User user = this.baseMapper.selectOne(new QueryWrapper<User>().eq("idcard", idcard));
        if (user==null){
            throw new MyException(ResultCode.ERROR,"账号或密码错误");
        }

        if(!new BCryptPasswordEncoder().matches(password, user.getPassword())){
            throw new MyException(ResultCode.ERROR,"账号或密码错误");
        }
        Policy policy = policyService.getUserPolicyById(user.getId()); //用户初筛
        String userPolicy = encapsulationUserPolicy(policy);

        HashMap<String, String> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("id",String.valueOf(user.getId()));
        objectObjectHashMap.put("policy",userPolicy);

        objectObjectHashMap.put("age", GetAgeUtil.getAgeByPsptNo(user.getIdcard()).toString()); //计算用户年龄
        String token = jwtUtil.createToken(objectObjectHashMap);
        LoginInfoVo loginInfoVo = new LoginInfoVo();
        BeanUtils.copyProperties(user,loginInfoVo);
        //登录成功返回token和用户信息
        return R.ok().data("token",token).data("item",loginInfoVo);
    }


    //用户注册
    @Override
    public R register(RegisterVo registerVo) {
        String idcard = registerVo.getIdcard();
        String name = registerVo.getName();
        String password = registerVo.getPassword();
        String telphone = registerVo.getTelphone();
        String fullname = registerVo.getFullname();
        if (    StringUtils.isEmpty(idcard) ||
                StringUtils.isEmpty(name) ||
                StringUtils.isEmpty(password) ||
                StringUtils.isEmpty(telphone) ||
                StringUtils.isEmpty(fullname) ){
            throw new MyException(ResultCode.ERROR,"用户信息填写不完整");
        }
        //查询数据库中是否存在相同的身份证号
        Long count = this.baseMapper.selectCount(new QueryWrapper<User>().eq("idcard", idcard));
        if(count.intValue() > 0) {
            throw new MyException(ResultCode.ERROR,"身份证已经注册过了");
        }
        User user = new User();
        BeanUtils.copyProperties(registerVo,user);
        user.setGender(0);  //性别 默认未知
        user.setCreateTime(new Date(System.currentTimeMillis()));  //用户创建时间
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(password);
        user.setPassword(encode);
        this.save(user);
        return R.ok();
    }

    @Override
    public int updateUser(User user) {
        return baseMapper.updateById(user);
    }

    @Override
    //得到用户所有订单
    public HashMap<String, Object> getAllOrder(Integer pageNum,HttpServletRequest request) {
        //获取用户token
        DecodedJWT tokenInfo = JwtUtil.getTokenInfo(request.getHeader(jwtUtil.getHeader()));
        String uid = tokenInfo.getClaim("id").asString();  //获得token中携带的用户id
        Page<SeckillOrder> seckillOrderPage = new Page<>(pageNum,8);
        Page<SeckillOrder> list = seckillOrderService.getUserOrderByUid(seckillOrderPage,uid);
        HashMap<String, Object> map = new HashMap<>();
        List eightInfo = this.getEightInfo(list.getRecords(), pageNum);
        map.put("data",eightInfo);
        map.put("total",list.getRecords().size());
        return map;
    }

    @Override
    public R delUserOrder(PayVo payVo, HttpServletRequest request) {
        //获取用户token
        DecodedJWT tokenInfo = JwtUtil.getTokenInfo(request.getHeader(jwtUtil.getHeader()));
        String uid = tokenInfo.getClaim("id").asString();  //获得token中携带的用户id

        int i = seckillOrderService.delUserOrder(payVo, uid);
        if (i==1){
            return R.ok();
        }
        else
        {return R.error();
        }
    }

    @Override
    public R alterPassword(AlterPasswordVo passwordVo, HttpServletRequest request) {
        //获取用户token
        DecodedJWT tokenInfo = JwtUtil.getTokenInfo(request.getHeader(jwtUtil.getHeader()));
        String uid = tokenInfo.getClaim("id").asString();  //获得token中携带的用户id
        if (StringUtils.isEmpty(uid)){
            throw new MyException(ResultCode.ERROR,"用户信息异常");
        }
        String password = passwordVo.getPassword();//得到前端传回
        String password1 = passwordVo.getPassword1();
        String password2 = passwordVo.getPassword2();
        String verification = passwordVo.getVerification();
        User user = baseMapper.selectById(uid);
        if (!password1.equals(password2)){
            throw new MyException(ResultCode.ERROR,"两次密码不一致");
        }
        String answer = (String) redisTemplate.opsForValue().get("VerifyCode:" + uid);
        if (answer==null){
            throw new MyException(ResultCode.ERROR,"验证码已过期");
        }
        if (!answer.equals(verification)){
            throw new MyException(ResultCode.ERROR,"验证码错误");
        }
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        if (!bCryptPasswordEncoder.matches(password,user.getPassword())){
            throw new MyException(ResultCode.ERROR,"密码错误");
        }
        String encode1 = bCryptPasswordEncoder.encode(password1);
        user.setPassword(encode1);
        baseMapper.updateById(user);
        return R.ok().data("data","修改成功");
    }

    /**
     * 得到用户信息
     * @param request
     * @return
     */
    @Override
    public R getUserInfo(HttpServletRequest request) {
        //获取用户token
        DecodedJWT tokenInfo = JwtUtil.getTokenInfo(request.getHeader(jwtUtil.getHeader()));
        String uid = tokenInfo.getClaim("id").asString();  //获得token中携带的用户id
        if (StringUtils.isEmpty(uid)){
            throw new MyException(ResultCode.ERROR,"用户信息异常");
        }
        User user = baseMapper.selectById(uid);
        return R.ok().data("data",user);
    }

    //根据页码获取八条数据
    public List getEightInfo(List list, Integer page) {
        if (list == null || list.size() <= 0) {
            return null;
        }
        ArrayList<Object> objects = new ArrayList(8);
        int index = (page - 1) * 8;
        int length = list.size();
        for (int i = 0; i < 8; i++) {
            if (index < length) {
                objects.add(list.get(index++));
            } else {
                break;
            }
        }
        return objects;
    }
    //封装用户初筛条件
    public String encapsulationUserPolicy(Policy policy){
        String policyCondition="";
        if (policy==null){
            return "111";
        }
        if (policy.getOverdue()==null||policy.getOverdue()==1){
            policyCondition=policyCondition+"1";
        }else{
            policyCondition=policyCondition+"0";
        }

        if (policy.getJob()==null||policy.getJob()==1){
            policyCondition=policyCondition+"1";
        }else{
            policyCondition=policyCondition+"0";
        }

        if (policy.getDishonesty()==null||policy.getDishonesty()==1){
            policyCondition=policyCondition+"1";
        }else{
            policyCondition=policyCondition+"0";
        }

        return policyCondition;

    }
}
